package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.modeling.model.dto.TyplmGeneralOperationDTO;
import com.hustcad.plm.pdm.mpm.model.dto.book.param.TyplmTechnologyBookCardParam;
import com.hustcad.plm.pdm.mpm.model.dto.capp.TyplmTechnologyBookCardWFObjInfo;
import com.hustcad.plm.pdm.mpmlink.service.file.TyplmMpmFileService;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainer;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.lark.oapi.okhttp.*;
import com.ty.basic.constant.TableTypeConstrant;
import cqrtplm.common.CommonService;
import cqrtplm.dto.ProcessRouteInfoDTO;
import cqrtplm.mapper.RTProcessMapper;
import cqrtplm.service.MOMIntegrityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MOMIntegrityServiceImpl implements MOMIntegrityService {

    @Resource
    private RTTyplmCappMpmCardServiceImpl typlmCappMpmCardService;
    @Resource
    private RTProcessMapper rtProcessMapper;
    @Resource
    private TyplmMpmFileService typlmMpmFileService;
    @Resource
    private CommonService commonService;
    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Value("${mom.process.info.url:http://192.168.102.70:30080/hitf/v2p/rest/invoke/UkFUTzpFU09QLU1FUzpydC1tZXMuaG1lLWVzb3AtaWZhY2UuZXNvcERhdGFJZmFjZQ==}")
    private String processInfoUrl;
    @Value("${mom.integrity.token.url:http://192.168.102.70:30080/oauth/oauth/token?grant_type=client_credentials&client_id=esopiface&client_secret=esopiface}")
    private String tokenUrl;

    @Override
    public void sendProcessRouteInfoToMOM(BigInteger workFlowContainerId) {
        TyplmTechnologyBookCardParam wfInfo = new TyplmTechnologyBookCardParam();
        wfInfo.setWorkFlowContainerId(workFlowContainerId);
        List<TyplmTechnologyBookCardWFObjInfo> list = typlmCappMpmCardService.getMpmObjectListByWf(wfInfo);
        Set<BigInteger> oids = list.stream().map(TyplmTechnologyBookCardWFObjInfo::getOid).collect(
                Collectors.toSet());
        List<ProcessRouteInfoDTO> processRouteInfoDTOList = rtProcessMapper.selectProcessInfoByOids(oids);
        if(CollUtil.isEmpty(processRouteInfoDTOList)){
            return;
        }
        Map<String, ProcessRouteInfoDTO> processRouteInfoDTOMap = processRouteInfoDTOList.stream().collect(
                Collectors.toMap(ProcessRouteInfoDTO::getProcessId, dto -> dto ,(existing, replacement) -> replacement));

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes != null ? attributes.getRequest() : null;

        Map<String, List<JSONObject>> fileMap = getCappFlies(oids, request);
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);
        WorkFlowContainer workFlowContainer = this.typlmWorkFlowContainerService.selectOneByOid(wfInfo.getWorkFlowContainerId());
        String code = workFlowContainer.getCode();
        String filePath = "工艺文件/" + formattedDate + "/" + code + "/";
        for (Map.Entry<String, List<JSONObject>> entry : fileMap.entrySet()) {
            String key = entry.getKey();
            List<JSONObject> valueList = entry.getValue();
            ProcessRouteInfoDTO processRouteInfoDTO = processRouteInfoDTOMap.get(key);
            if(ObjectUtils.isEmpty(processRouteInfoDTO) || CollUtil.isEmpty(valueList)){
                continue;
            }
            List<String> filePathList = new ArrayList<>();
            for (JSONObject jsonObject : valueList) {
                BigInteger fileId = jsonObject.getBigInteger("fileid");
                String url = commonService.downloadFileToFtp(fileId, filePath);
                filePathList.add( url);
            }
            processRouteInfoDTO.setFileType(1);
            processRouteInfoDTO.setFileUrl(String.valueOf(filePathList));
        }
        List<ProcessRouteInfoDTO> processRouteInfoDTOS = new ArrayList<>(processRouteInfoDTOMap.values());
        String info = JSONArray.toJSONString(processRouteInfoDTOS);
        log.info("===========提示信息============> 发送MOM信息为：{}", info);
        sendInfoToMOM(info);
    }

    private void sendInfoToMOM(String info) {
        String momToken = getMomToken();
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, info);
        Request request = new Request.Builder()
                .url(processInfoUrl)
                .method("POST", body)
                .addHeader("Authorization", momToken)
                .addHeader("Content-Type", "application/json")
                .build();
        try {
            Response response = client.newCall(request).execute();
            String str = response.body().string();
            JSONObject json = JSONObject.parseObject(str);
            String status = json.getJSONObject("rows").getString("status");
            log.info("响应结果："+str);
            if (status.equals("S")){
                log.info("发送MOM成功");
            }else {
                String errMessage = json.getJSONObject("rows").getJSONObject("detail").getString("processMessage");
                log.error("发送MOM失败，错误原因：",errMessage);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String getMomToken() {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("text/plain");
        RequestBody body = RequestBody.create(mediaType, "");
        Request request = new Request.Builder()
                .url(tokenUrl)
                .method("POST", body)
                .build();
        Response response = null;
        try {
            response = client.newCall(request).execute();
            String data = response.body().string();
            JSONObject jsonObject = JSONObject.parseObject(data);
            return jsonObject.getString("access_token");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private Map<String, List<JSONObject>> getCappFlies(Set<BigInteger> oids, HttpServletRequest request) {
        Map<String, List<JSONObject>> map = new HashMap<>();
        TyplmGeneralOperationDTO dto = new TyplmGeneralOperationDTO();
        for (BigInteger oid : oids) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("otype", TableTypeConstrant.TY_MPMOPERATION_TYPE);
            jsonObject.put("oid", oid);
            dto.setParentObj(jsonObject);
            List<JSONObject> objectList = this.typlmMpmFileService.queryFileListNotMpmgyft(request, dto);
            map.put(oid.toString(), objectList);
        }
        return map;
    }
}

